package com.inspectortime.domain;

import java.util.Calendar;
import java.util.Date;
import java.util.List;

import javax.persistence.Transient;

import com.inspectortime.common.Identifiable;
import com.inspectortime.domain.type.FrequencyType;
import com.inspectortime.domain.type.Time;
import com.inspectortime.util.CalendarUtil;

/**
 * Represents a singular rule to represent an Inspector's availability in a given time slot
 * over a given period of time (FrequencyType) 
 * 
 * Note: ScheduleRule have an order of sort priority based on Frequency Type. The rule with higher 
 * priority will override that with lower.
 * 
 * Lowest to highest:
 *  Day of Week (ex. every mon of the week)
 * 	Single Day (ex. 10/20/08)
 * 
 * @author Owner
 * @version 1.0
 * @created 27-Nov-2007 7:40:35 AM
 */
public interface ScheduleRule extends Identifiable {
	
	/**
	 * Return the frequency type for this schedule rule
	 * 
	 * @return frequencyType
	 */
	FrequencyType getFrequencyType();
	
	/**
	 * @param frequencyType
	 */
	void setFrequencyType(FrequencyType frequencyType);
	
	/**
	 * Return an array of integers representing additional information
	 * that a scheduleRule may require.  Currently these are only used
	 * to represent days of week for a schedule rule with FrequencyType.WEEKLY.
	 * These can be used for future frequency types as needed.
	 * 
	 * @return
	 */
	int[] getUnits();
	
	/**
	 * Set the schedule rule units, if needed.
	 * 
	 * @param units
	 */
	void setUnits(int[] units);
	
	/**
	 * Returns the units in a list of human-readable Strings
	 * ie if frequencyType is WEEKLY, units will be returned as "Sunday", "Monday", etc
	 * 
	 * NOTE: Currently we only have units for WEEKLY scheduleRules.  If this changes, we'll
	 * need to modify the implementation
	 * 
	 * @return human readable units
	 */
	List<String> getUnitsForDisplay();
	
	
	/**
	 * Returns an integer representing the hour of the day in which this scheduleRule begins (0-24)
	 * 
	 * @return startHour
	 */
	int getStartHour();
	
	/**
	 * Set an integer representing the hour of the day in which this scheduleRule begins (0-24)
	 * 
	 * @param the start hour
	 */
	void setStartHour(int hour);
	
	/**
	 * Returns an integer representing the minute of the hour in which this scheduleRule begins (0-60)
	 * 
	 * @return startHour
	 */
	int getStartMinute();
	
	/**
	 * Set an integer representing the minute of the hour in which this scheduleRule begins (0-60)
	 * 
	 * @param minute
	 */
	void setStartMinute(int minute);
	
	/**
	 * Returns an integer representing the hour of the day in which this scheduleRule ends (0-24)
	 * 
	 * @return endHour
	 */
	int getEndHour();
	
	/**
	 * Set an integer representing the hour of the day in which this scheduleRule ends (0-24)
	 * 
	 * @param the endHour
	 */
	void setEndHour(int hour);
	
	/**
	 * Returns an integer representing the minute of the hour in which this scheduleRule ends (0-60)
	 * 
	 * @return startHour
	 */
	int getEndMinute();
	
	/**
	 * Set an integer representing the minute of the hour in which this scheduleRule ends (0-60)
	 * 
	 * @param minute
	 */
	void setEndMinute(int minute);
	
	/**
	 * Return a Calendar representing the particular day that this scheduleRule begins, or null
	 * if the scheduleRule has no start date
	 * 
	 * @return startDate
	 */
	Calendar getStartDate();
	
	/**
	 * Set a Calendar representing the particular day that this scheduleRule begins
	 * 
	 * @return startDate
	 */
	void setStartDate(Calendar startDate);
	
	/**
	 * Return a Calendar representing the particular day that this scheduleRule ends, or null
	 * if the scheduleRule has no end date (continues indefinitely)
	 * 
	 * @return startDate
	 */
	Calendar getEndDate();
	
	/**
	 * Set a Calendar representing the particular day that this scheduleRule ends
	 * 
	 * @return endDate
	 */
	void setEndDate(Calendar endDate);
	
	/**
	 * Return true if this scheduleRule represents a timeslot in which the Inspector is available for service,
	 * or false if the inspector is not available for service
	 * 
	 * @return isAvailable
	 */
	boolean isAvailable();

	/**
	 * Set to true if this scheduleRule represents a timeslot in which the Inspector is available for service,
	 * or false if the inspector is not available for service
	 * 
	 * @param isAvailable
	 */
	void setAvailable(boolean available);
	
	boolean conflictsWith(ScheduleRule compareRule);
	
	Time getStartTime();
	Time getEndTime();	
}